﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.Sql;
using System.Data.SqlClient;
using System.Windows;
using System.Windows.Controls;

namespace XMM.Objects
{
    public class SeriesEpisode : Object
    {
        /// <summary>
        /// Database-Record ID.
        /// </summary>
        public int EpisodeID { get; set; }

        /// <summary>
        /// Database-Record ID of the corresponding Series.
        /// </summary>
        public int SeriesID { get; set; }

        /// <summary>
        /// Database-Record ID of the corresponding Season.
        /// </summary>
        public int SeasonID { get; set; }

        /// <summary>
        /// Name or Title of the Episode.
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// Plot of this Episode.
        /// </summary>
        public string Plot { get; set; }

        /// <summary>
        /// Audio-Info extracted from Media.
        /// </summary>
        public Objects.AudioInfo AudioInfo { get; set; }

        /// <summary>
        /// Video-Info extracted from Media.
        /// </summary>
        public Objects.VideoInfo VideoInfo { get; set; }

        /// <summary>
        /// Database-ID of the assigned disk-media.
        /// </summary>
        public int DiskMediaID { get; set; }

        /// <summary>
        /// Number of this Episode it's Season.
        /// </summary>
        public int EpisodeNo { get; set; }

        /// <summary>
        /// Video-HD-Level.
        /// </summary>
        /// <remarks>0...Standard Definition (SD)
        /// 1...HD 720p
        /// 2...HD 1080i
        /// 3...HD 1080p</remarks>
        public int HDLevel { get; set; }

        /// <summary>
        /// Full path to media-file.
        /// </summary>
        public string MediaFile { get; set; }

        /// <summary>
        /// Initialize a new Episode-Object.
        /// </summary>
        public SeriesEpisode()
        {
            blankValues();
        }

        /// <summary>
        /// Initialize a new Episode-Object from database-record.
        /// </summary>
        /// <param name="iEpisodeID">(int) Target-Episode Database-ID</param>
        public SeriesEpisode(int iEpisodeID)
        {
            Load(iEpisodeID);
        }

        /// <summary>
        /// Reset all values.
        /// </summary>
        public void blankValues()
        {
            EpisodeID = 0;
            SeriesID = 0;
            SeasonID = 0;
            Name = String.Empty;
            Plot = String.Empty;
            AudioInfo = new Objects.AudioInfo();
            VideoInfo = new Objects.VideoInfo();
            HDLevel = 0;
            MediaFile = String.Empty;
            DiskMediaID = 0;
            EpisodeNo = 0;
        }

        public override string ToString()
        {
            string sEpisodeIdentity = String.Empty;
            sEpisodeIdentity = "(" + EpisodeID.ToString() + ")";

            if (Name != String.Empty)
                sEpisodeIdentity += " " + Name;

            return Name;
        }

        public bool SeenBy(int iAudienceID)
        {
            if (EpisodeID != 0)
            {
                XMMDBDataContext dbConnection = new XMMDBDataContext();

                var vPlaybackCounter = (from playbacks in dbConnection.t_history where playbacks.MediaType == 2 && playbacks.MediaID == EpisodeID && playbacks.AudienceID == iAudienceID select playbacks).Count();

                if ((int)vPlaybackCounter > 0)
                {
                    return true;
                }
            }

            return false;
        }

        /// <summary>
        /// Load values from database-record.
        /// </summary>
        /// <param name="iEpisodeID">(int) Target-Episode Database-ID</param>
        /// <returns>[true] if record was loaded successfully.</returns>
        public bool Load(int iEpisodeID)
        {
            blankValues();

            if (iEpisodeID != 0)
            {
                try
                {
                    XMMDBDataContext dbConnection = new XMMDBDataContext();

                    var vEpisode = (from episode in dbConnection.t_series_episodes where episode.ID == iEpisodeID select episode).Single();

                    if (vEpisode != null && vEpisode.ID != 0)
                    {
                        // Assign values.
                        EpisodeID = vEpisode.ID;
                        SeriesID = vEpisode.SeriesID;
                        SeasonID = vEpisode.SeasonID;
                        if (vEpisode.Name != null)
                            Name = vEpisode.Name;
                        if (vEpisode.Plot != null)
                            Plot = vEpisode.Plot;
                        if (vEpisode.AudioInfo != null)
                        {
                            AudioInfo = new Objects.AudioInfo();
                            AudioInfo.buildFromBinary(vEpisode.AudioInfo);
                        }
                        if (vEpisode.VideoInfo != null)
                        {
                            VideoInfo = new Objects.VideoInfo();
                            VideoInfo.buildFromBinary(vEpisode.VideoInfo);
                        }
                        HDLevel = vEpisode.HDLevel;
                        if (vEpisode.Files != null)
                            MediaFile = vEpisode.Files;
                        DiskMediaID = vEpisode.DiskMediaID;
                        if (vEpisode.EpisodeNo != null)
                            EpisodeNo = vEpisode.EpisodeNo;

                        return true;
                    }
                }
                catch (SqlException ex)
                {
                    MessageBox.Show("Fehler beim Laden der Episoden-Infos: " + ex.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
                }
            }

            return false;
        }

        public static bool Delete(int iEpisodeID)
        {
            if (iEpisodeID != 0)
            {
                try
                {
                    XMMDBDataContext dbConnection = new XMMDBDataContext();

                    t_series_episodes vEpisode = (from episode in dbConnection.t_series_episodes where episode.ID == iEpisodeID select episode).Single();

                    if (vEpisode != null && vEpisode.ID > 0)
                    {
                        dbConnection.t_series_episodes.DeleteOnSubmit(vEpisode);
                        dbConnection.SubmitChanges();

                        return true;
                    }
                }
                catch (SqlException ex)
                {
                    MessageBox.Show("Fehler beim Löschen der Folge: " + ex.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
                }
            }

            return false;
        }

        public bool RelocateHDD(string sNewDriveLetter)
        {
            return Objects.SeriesEpisode.RelocateHDD(EpisodeID, sNewDriveLetter);
        }

        public static bool RelocateHDD(int iEpisodeID, string sNewDriveLetter)
        {
            Objects.SeriesEpisode oEpisode = new SeriesEpisode(iEpisodeID);

            if (oEpisode != null && oEpisode.EpisodeID != 0)
            {
                oEpisode.MediaFile = sNewDriveLetter + oEpisode.MediaFile.Remove(0, 1);

                return oEpisode.SaveChanges();
            }

            return false;
        }

        public bool Delete()
        {
            return Objects.SeriesEpisode.Delete(EpisodeID);
        }

        /// <summary>
        /// Save this episode object as new database-record.
        /// </summary>
        /// <returns>[true] if record was saved successfully</returns>
        public bool SaveNew()
        {
            if (SeriesID != 0 && SeasonID != 0 && MediaFile != String.Empty && EpisodeNo != 0)
            {
                try
                {
                    XMMDBDataContext dbConnection = new XMMDBDataContext();

                    t_series_episodes vEpisode = new t_series_episodes();
                    vEpisode.SeriesID = SeriesID;
                    vEpisode.SeasonID = SeasonID;
                    vEpisode.Name = Name;
                    vEpisode.Plot = Plot;
                    vEpisode.AudioInfo = AudioInfo.ToBinary();
                    vEpisode.VideoInfo = VideoInfo.ToBinary();
                    vEpisode.HDLevel = HDLevel;
                    vEpisode.Files = MediaFile;
                    vEpisode.EpisodeNo = EpisodeNo;
                    vEpisode.DiskMediaID = DiskMediaID;

                    dbConnection.t_series_episodes.InsertOnSubmit(vEpisode);
                    dbConnection.SubmitChanges();

                    return true;
                }
                catch (SqlException ex)
                {
                    MessageBox.Show("Fehler beim Speichern der neuen Episode: " + ex.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
                }
            }
            else
            {
                if (SeriesID == 0)
                    MessageBox.Show("Bitte wählen Sie eine Serie aus!", "Fehlende Angaben", MessageBoxButton.OK, MessageBoxImage.Exclamation);
                if (SeasonID == 0)
                    MessageBox.Show("Bitte wählen Sie eine Staffel aus!", "Fehlende Angaben", MessageBoxButton.OK, MessageBoxImage.Exclamation);
                if (MediaFile == String.Empty)
                    MessageBox.Show("Bitte wählen Sie eine Video-Datei aus!", "Fehlende Angaben", MessageBoxButton.OK, MessageBoxImage.Exclamation);
                if (EpisodeNo == 0)
                    MessageBox.Show("Bitte geben Sie die Nummer der Episode ein!", "Fehlende Angaben", MessageBoxButton.OK, MessageBoxImage.Exclamation);
            }

            return false;
        }

        /// <summary>
        /// Save changes to an existing database-record.
        /// </summary>
        /// <returns>[true] if record was updated successfully</returns>
        public bool SaveChanges()
        {
            if (SeriesID != 0 && SeasonID != 0 && MediaFile != String.Empty && EpisodeID != 0 && EpisodeNo != 0)
            {
                try
                {
                    XMMDBDataContext dbConnection = new XMMDBDataContext();

                    t_series_episodes vEpisode = (from episode in dbConnection.t_series_episodes where episode.ID == EpisodeID select episode).Single();

                    if (vEpisode != null && vEpisode.ID != 0)
                    {
                        vEpisode.Name = Name;
                        vEpisode.SeriesID = SeriesID;
                        vEpisode.SeasonID = SeasonID;
                        vEpisode.Plot = Plot;
                        vEpisode.AudioInfo = AudioInfo.ToBinary();
                        vEpisode.VideoInfo = VideoInfo.ToBinary();
                        vEpisode.HDLevel = HDLevel;
                        vEpisode.Files = MediaFile;
                        vEpisode.EpisodeNo = EpisodeNo;
                        vEpisode.DiskMediaID = DiskMediaID;

                        dbConnection.SubmitChanges();
                        return true;
                    }
                    else
                    {
                        MessageBox.Show("Fehler beim Speichern der Änderungen an Episode '" + EpisodeID.ToString() + "': Die Episode wurde nicht in der Datenbank gefunden!", "Fehler", MessageBoxButton.OK, MessageBoxImage.Exclamation);
                    }
                }
                catch (SqlException ex)
                {
                    MessageBox.Show("Fehler beim Speichern der Änderungen an Episode '" + EpisodeID.ToString() + "': " + ex.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
                }
            }
            else
            {
                if (SeriesID == 0)
                    MessageBox.Show("Bitte wählen Sie eine Serie aus!", "Fehlende Angaben", MessageBoxButton.OK, MessageBoxImage.Exclamation);
                if (SeasonID == 0)
                    MessageBox.Show("Bitte wählen Sie eine Staffel aus!", "Fehlende Angaben", MessageBoxButton.OK, MessageBoxImage.Exclamation);
                if (MediaFile == String.Empty)
                    MessageBox.Show("Bitte wählen Sie eine Video-Datei aus!", "Fehlende Angaben", MessageBoxButton.OK, MessageBoxImage.Exclamation);
                if (EpisodeID == 0)
                    MessageBox.Show("Die ausgewählte Episode exisitiert noch nicht! Speichern Sie die Episode als neue Episode!", "Fehlende Angaben", MessageBoxButton.OK, MessageBoxImage.Exclamation);
                if (EpisodeNo == 0)
                    MessageBox.Show("Bitte geben Sie die Nummer der Episode ein!", "Fehlende Angaben", MessageBoxButton.OK, MessageBoxImage.Exclamation);
            }

            return false;
        }
    }
}
